package com.whfc.fuum.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.enums.AppType;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.AssertUtil;
import com.whfc.common.util.PageUtil;
import com.whfc.common.weixin.bean.OAuthUserInfo;
import com.whfc.common.weixin.mp.WXBizDataCrypt;
import com.whfc.common.weixin.mp.WxMpUserInfo;
import com.whfc.fuum.dao.SysUserMapper;
import com.whfc.fuum.dao.WxUserMapper;
import com.whfc.fuum.dto.WxUserDTO;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.entity.WxUser;
import com.whfc.fuum.param.WxUserParam;
import com.whfc.fuum.service.WxUserService;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.hibernate.validator.constraints.Length;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/22 11:25
 */
@DubboService(interfaceClass = WxUserService.class, version = "1.0.0")
public class WxUserServiceImpl implements WxUserService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxUserMapper wxUserMapper;
    @Autowired
    SysUserMapper sysUserMapper;

    @Override
    public PageData<WxUserDTO> wxmpUserList(Integer pageNum, Integer pageSize, String keyword, Integer appType, Date startDate, Date endDate) {
        PageHelper.startPage(pageNum, pageSize);
        List<WxUserDTO> list = wxUserMapper.selectWxUsers(keyword, appType, startDate, endDate);
        PageHelper.clearPage();
        return PageUtil.pageData(PageInfo.of(list));
    }

    @Override
    public WxUser getUserByOpenId(String openId) {
        return wxUserMapper.selectByOpenId(openId);
    }

    @Override
    public List<WxUser> getUserByPhone(String phone) {
        return wxUserMapper.selectByPhone(phone);
    }

    @Override
    public WxUser saveUser(AppType appType, String openId, String unionId, String sessionKey) {

        WxUser wxUser = wxUserMapper.selectByOpenId(openId);
        if (wxUser == null) {
            wxUser = new WxUser();
        }
        wxUser.setAppType(appType.value());
        wxUser.setOpenId(openId);
        wxUser.setUnionId(unionId);
        wxUser.setSessionKey(sessionKey);

        //通过unionId查询关联的手机号
        WxUser unionUser = wxUserMapper.selectPhoneByUnionId(unionId);
        if (unionUser != null) {
            wxUser.setPhone(unionUser.getPhone());
            wxUser.setNickName(unionUser.getNickName());
            wxUser.setAvatarUrl(unionUser.getAvatarUrl());
            wxUser.setName(unionUser.getName());
        }
        wxUserMapper.insertOrUpdate(wxUser);
        return wxUser;
    }

    @Override
    public WxUser saveUser(AppType appType, OAuthUserInfo userInfo) {
        String openId = userInfo.getOpenid();
        String unionId = userInfo.getUnionid();
        WxUser wxUser = wxUserMapper.selectByOpenId(openId);
        if (wxUser == null) {
            wxUser = new WxUser();
        }
        wxUser.setOpenId(openId);
        wxUser.setUnionId(unionId);
        wxUser.setAppType(appType.value());
        wxUser.setNickName(userInfo.getNickname());
        wxUser.setGender(userInfo.getSex());
        wxUser.setAvatarUrl(userInfo.getHeadimgurl());

        //通过unionId查询关联的手机号
        WxUser unionUser = wxUserMapper.selectPhoneByUnionId(unionId);
        if (unionUser != null) {
            wxUser.setPhone(unionUser.getPhone());
            wxUser.setNickName(unionUser.getNickName());
            wxUser.setAvatarUrl(unionUser.getAvatarUrl());
            wxUser.setName(unionUser.getName());
        }
        wxUserMapper.insertOrUpdate(wxUser);
        return wxUser;
    }

    @Override
    public WxUser getUserById(Integer wxUserId) {
        return wxUserMapper.selectByPrimaryKey(wxUserId);
    }

    @Override
    public WxUser updateUserInfo(WxUser wxUser, String encryptedData, String iv) {

        String sessionKey = wxUser.getSessionKey();
        logger.info("openId:{},sessionKey:{}", wxUser.getOpenId(), sessionKey);
        if (StringUtils.isEmpty(sessionKey)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "缺少sessionKey");
        }
        WxMpUserInfo userInfo = WXBizDataCrypt.decryptMpUsrInfo(sessionKey, encryptedData, iv);
        if (userInfo == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "解密用户信息失败");
        }
        wxUser.setOpenId(userInfo.getOpenId());
        wxUser.setUnionId(userInfo.getUnionId());
        wxUser.setGender(userInfo.getGender());
        wxUser.setNickName(userInfo.getNickName());
        wxUser.setAvatarUrl(userInfo.getAvatarUrl());
        wxUser.setPhone(userInfo.getPhoneNumber());
        wxUserMapper.updateByPrimaryKeySelective(wxUser);
        return wxUser;
    }

    @Override
    public void updateUserName(WxUser loginUser, String name) {
        loginUser.setName(name);
        wxUserMapper.updateByPrimaryKeySelective(loginUser);
    }


    @Override
    public void updateUserPhone(WxUser loginUser, String phone) throws BizException {
        //验证手机号是否被占用
        WxUser existUser = wxUserMapper.selectByAppTypeAndPhone(loginUser.getAppType(), phone);
        if (existUser != null && !existUser.getId().equals(loginUser.getId())) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "手机号已被其他账号使用");
        }

        //更新手机号
        loginUser.setPhone(phone);
        wxUserMapper.updateByPrimaryKeySelective(loginUser);
    }

    @Override
    public void updateUser(WxUser loginUser) {
        wxUserMapper.updateByPrimaryKeySelective(loginUser);
    }

    @Transactional
    @Override
    public void editUserInfo(WxUserParam param) {
        Integer wxUserId = param.getWxUserId();
        WxUser wxUser = Optional.ofNullable(wxUserMapper.selectByPrimaryKey(wxUserId)).orElseThrow(() -> AssertUtil.getException("用户信息不存在"));

        BeanUtils.copyProperties(param, wxUser);
        wxUser.setUpdateTime(new Date());
        wxUserMapper.updateByPrimaryKeySelective(wxUser);

        String password = param.getPassword();
        if (StringUtils.isEmpty(password)) {
            return;

        }

        String phone = wxUser.getPhone();
        AssertUtil.isTrue(StringUtils.isEmpty(phone), "用户手机号信息缺失,无法关联到用户信息");

        SysUser user = Optional.ofNullable(sysUserMapper.selectByPhone(phone)).orElseThrow(() -> AssertUtil.getException("手机号关联的用户信息不存在"));
        String pwd = new SimpleHash("MD5", password, user.getSalt()).toString();
        user.setPassword(pwd);
        user.setUpdateTime(new Date());
        sysUserMapper.updateByPrimaryKeySelective(user);
    }


}
